/*
 * Copyright 2010 Alessandro Bellucci
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.soupframework.gwt.designerpanel.client.command.impl;

import org.soupframework.gwt.designerpanel.client.designer.ContainerDesigner;
import org.soupframework.gwt.designerpanel.client.designer.OperatingMode;
import org.soupframework.gwt.designerpanel.client.designer.impl.AbsolutePanelViewDesigner;
import org.soupframework.gwt.designerpanel.client.grid.GridMode;
import org.soupframework.gwt.designerpanel.client.grid.Grid.GridVertex;
import org.soupframework.gwt.designerpanel.client.util.Util;

import com.google.gwt.user.client.ui.Widget;

public abstract class AbsolutePanelDesignerCommandBase<T> extends ComplexPanelDesignerCommandBase<T> {

	public AbsolutePanelDesignerCommandBase(ContainerDesigner<T> designer) {
		super(designer);
	}

	public AbsolutePanelViewDesigner<T> getDesigner(){
		return (AbsolutePanelViewDesigner<T>)super.getDesigner();
	}

	/**
	 * Moves the widget by a specified amount of pixels
	 *
	 * @param w
	 * @param deltaX The amount to move the widget in the horizontal direction
	 * @param deltaY The amount to move the widget in the vertical direction
	 */
	protected void moveWidget(Widget w, int deltaX, int deltaY, boolean blockGridAlignment){
		if(this.getDesigner().getManager().getOperatingMode() == OperatingMode.LIVE_MODE){
			return;
		}
		checkWidgetParent(w);
		Integer left = Util.getWidgetStyleLeft(w);
		Integer top = Util.getWidgetStyleTop(w);
		if(left != null && top != null){
			this.setWidgetPositionImpl(w, left + deltaX, top + deltaY, blockGridAlignment);
		}
	}

	/**
	 * Sets the {@link Widget} position
	 *
	 * @param w
	 * @param left the left coordinate of the upper left corner
	 * @param top the top coordinate of the upper left corner
	 * @param blockGridAlignment if true alignment to grid is always avoided
	 */
	protected void setWidgetPositionImpl(Widget w, int left, int top, boolean blockGridAlignment) {
		if(!blockGridAlignment && this.getDesigner().getManager().getGridMode() == GridMode.AUTO_ALIGN){
			GridVertex gridVertex = this.getDesigner().getManager().getDesignerPanel().getGrid().getClosestGridVertex(left, top);
			left = gridVertex.getX();
			top = gridVertex.getY();
		}
		getDesigner().getObjectView().setWidgetPosition(w, left, top);
	}

	/**
	 * Checks whether the specified widget is a child of DesignerPanel and throws an Exception if not
	 * This operation is a no-op if operating mode is LIVE
	 *
	 * @param w The widget
	 */
	private void checkWidgetParent(Widget w){
		if(w.getParent() != this.getDesigner().getObjectView()){
			throw new IllegalArgumentException("Widget must be a child of this panel.");
		}
	}
}
